'use client';

import { useState, useEffect, useCallback } from 'react';
import { cn } from '@/lib/utils';
import { Loader2, Zap, Code, Cpu, Database, Network } from 'lucide-react';

/**
 * 页面加载动画组件
 */
interface PageLoadingProps {
  isLoading?: boolean;
  variant?: 'default' | 'tech' | 'minimal' | 'gradient' | 'particles';
  message?: string;
  progress?: number;
  className?: string;
}

export function PageLoading({
  isLoading = true,
  variant = 'default',
  message = '正在加载...',
  progress,
  className,
}: PageLoadingProps) {
  const [dots, setDots] = useState('');
  const [currentStep, setCurrentStep] = useState(0);

  const loadingSteps = [
    { icon: Code, text: '初始化系统' },
    { icon: Database, text: '加载数据' },
    { icon: Network, text: '建立连接' },
    { icon: Cpu, text: '准备就绪' },
  ];

  useEffect(() => {
    if (!isLoading) return;

    const interval = setInterval(() => {
      setDots(prev => {
        if (prev.length >= 3) return '';
        return prev + '.';
      });
    }, 500);

    return () => clearInterval(interval);
  }, [isLoading]);

  useEffect(() => {
    if (!isLoading || variant !== 'tech') return;

    const interval = setInterval(() => {
      setCurrentStep(prev => (prev + 1) % loadingSteps.length);
    }, 1000);

    return () => clearInterval(interval);
  }, [isLoading, variant, loadingSteps.length]);

  if (!isLoading) return null;

  // 默认加载动画
  if (variant === 'default') {
    return (
      <div
        className={cn(
          'fixed inset-0 z-50 flex items-center justify-center bg-white dark:bg-gray-900',
          className
        )}
      >
        <div className="text-center">
          <Loader2 className="w-8 h-8 animate-spin text-blue-600 mx-auto mb-4" />
          <p className="text-gray-600 dark:text-gray-400">
            {message}
            {dots}
          </p>
          {progress !== undefined && (
            <div className="mt-4 w-64 bg-gray-200 dark:bg-gray-700 rounded-full h-2">
              <div
                className="bg-blue-600 h-2 rounded-full transition-all duration-300"
                style={{ width: `${progress}%` }}
              />
            </div>
          )}
        </div>
      </div>
    );
  }

  // 科技风格加载动画
  if (variant === 'tech') {
    const CurrentIcon = loadingSteps[currentStep].icon;

    return (
      <div
        className={cn(
          'fixed inset-0 z-50 flex items-center justify-center bg-gradient-to-br from-gray-900 via-blue-900 to-purple-900',
          className
        )}
      >
        <div className="text-center text-white">
          {/* 主要图标 */}
          <div className="relative mb-8">
            <div className="w-20 h-20 mx-auto rounded-full bg-blue-600/20 flex items-center justify-center">
              <CurrentIcon className="w-10 h-10 text-blue-400" />
            </div>

            {/* 脉冲动画 */}
            <div className="absolute inset-0 w-20 h-20 mx-auto rounded-full bg-blue-600/10 animate-ping" />
            <div className="absolute inset-2 w-16 h-16 mx-auto rounded-full bg-blue-600/20 animate-pulse" />
          </div>

          {/* 加载步骤 */}
          <div className="space-y-2 mb-6">
            <h3 className="text-xl font-semibold">CActor Framework</h3>
            <p className="text-blue-200">
              {loadingSteps[currentStep].text}
              {dots}
            </p>
          </div>

          {/* 进度指示器 */}
          <div className="flex justify-center space-x-2">
            {loadingSteps.map((_, index) => (
              <div
                key={index}
                className={cn(
                  'w-2 h-2 rounded-full transition-all duration-300',
                  index === currentStep
                    ? 'bg-blue-400 scale-125'
                    : index < currentStep
                      ? 'bg-blue-600'
                      : 'bg-gray-600'
                )}
              />
            ))}
          </div>
        </div>
      </div>
    );
  }

  // 最小化加载动画
  if (variant === 'minimal') {
    return (
      <div
        className={cn(
          'fixed inset-0 z-50 flex items-center justify-center bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm',
          className
        )}
      >
        <div className="flex items-center space-x-3 bg-white dark:bg-gray-800 px-6 py-4 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700">
          <div className="w-5 h-5 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
          <span className="text-gray-700 dark:text-gray-300 font-medium">
            {message}
          </span>
        </div>
      </div>
    );
  }

  // 渐变加载动画
  if (variant === 'gradient') {
    return (
      <div
        className={cn(
          'fixed inset-0 z-50 flex items-center justify-center bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-gray-900 dark:via-blue-900 dark:to-purple-900',
          className
        )}
      >
        <div className="text-center">
          <div className="relative mb-6">
            <div className="w-16 h-16 mx-auto rounded-full bg-gradient-to-r from-blue-500 to-purple-600 animate-spin">
              <div className="absolute inset-2 bg-white dark:bg-gray-900 rounded-full" />
            </div>
          </div>

          <h3 className="text-2xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent mb-2">
            CActor
          </h3>
          <p className="text-gray-600 dark:text-gray-400">
            {message}
            {dots}
          </p>
        </div>
      </div>
    );
  }

  // 粒子效果加载动画
  if (variant === 'particles') {
    return (
      <div
        className={cn(
          'fixed inset-0 z-50 flex items-center justify-center bg-gray-900',
          className
        )}
      >
        <div className="relative">
          {/* 粒子背景 */}
          <div className="absolute inset-0 overflow-hidden">
            {Array.from({ length: 20 }).map((_, i) => (
              <div
                key={i}
                className="absolute w-1 h-1 bg-blue-400 rounded-full animate-pulse"
                style={{
                  left: `${Math.random() * 100}%`,
                  top: `${Math.random() * 100}%`,
                  animationDelay: `${Math.random() * 2}s`,
                  animationDuration: `${2 + Math.random() * 2}s`,
                }}
              />
            ))}
          </div>

          {/* 主内容 */}
          <div className="relative z-10 text-center text-white">
            <Zap className="w-12 h-12 mx-auto mb-4 text-blue-400 animate-bounce" />
            <h3 className="text-xl font-semibold mb-2">CActor Framework</h3>
            <p className="text-blue-200">
              {message}
              {dots}
            </p>
          </div>
        </div>
      </div>
    );
  }

  return null;
}

/**
 * 页面过渡动画组件
 */
interface PageTransitionProps {
  children: React.ReactNode;
  variant?: 'fade' | 'slide' | 'scale' | 'blur' | 'flip';
  duration?: number;
  className?: string;
}

export function PageTransition({
  children,
  variant = 'fade',
  duration = 300,
  className,
}: PageTransitionProps) {
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => {
    setIsVisible(true);
  }, []);

  const getTransitionClasses = () => {
    const baseClasses = 'transition-all ease-out';
    const durationClass = `duration-${duration}`;

    switch (variant) {
      case 'slide':
        return cn(
          baseClasses,
          durationClass,
          isVisible ? 'translate-x-0 opacity-100' : 'translate-x-8 opacity-0'
        );
      case 'scale':
        return cn(
          baseClasses,
          durationClass,
          isVisible ? 'scale-100 opacity-100' : 'scale-95 opacity-0'
        );
      case 'blur':
        return cn(
          baseClasses,
          durationClass,
          isVisible ? 'blur-0 opacity-100' : 'blur-sm opacity-0'
        );
      case 'flip':
        return cn(
          baseClasses,
          durationClass,
          isVisible ? 'rotate-0 opacity-100' : 'rotate-12 opacity-0'
        );
      default: // fade
        return cn(
          baseClasses,
          durationClass,
          isVisible ? 'opacity-100' : 'opacity-0'
        );
    }
  };

  return (
    <div className={cn(getTransitionClasses(), className)}>{children}</div>
  );
}

/**
 * 骨架屏加载组件
 */
interface SkeletonProps {
  className?: string;
  variant?: 'text' | 'rectangular' | 'circular' | 'card';
  animation?: 'pulse' | 'wave' | 'none';
  lines?: number;
}

export function Skeleton({
  className,
  variant = 'text',
  animation = 'pulse',
  lines = 1,
}: SkeletonProps) {
  const getAnimationClass = () => {
    switch (animation) {
      case 'wave':
        return 'animate-pulse bg-gradient-to-r from-gray-200 via-gray-300 to-gray-200 dark:from-gray-700 dark:via-gray-600 dark:to-gray-700 bg-[length:200%_100%] animate-[wave_1.5s_ease-in-out_infinite]';
      case 'none':
        return 'bg-gray-200 dark:bg-gray-700';
      default:
        return 'animate-pulse bg-gray-200 dark:bg-gray-700';
    }
  };

  const getVariantClasses = () => {
    switch (variant) {
      case 'rectangular':
        return 'rounded-md';
      case 'circular':
        return 'rounded-full';
      case 'card':
        return 'rounded-lg';
      default:
        return 'rounded';
    }
  };

  if (variant === 'card') {
    return (
      <div className={cn('space-y-3', className)}>
        <div className={cn('h-4 w-3/4 rounded', getAnimationClass())} />
        <div className={cn('h-4 w-1/2 rounded', getAnimationClass())} />
        <div className={cn('h-32 w-full rounded-lg', getAnimationClass())} />
        <div className="space-y-2">
          <div className={cn('h-3 w-full rounded', getAnimationClass())} />
          <div className={cn('h-3 w-5/6 rounded', getAnimationClass())} />
        </div>
      </div>
    );
  }

  if (lines > 1) {
    return (
      <div className={cn('space-y-2', className)}>
        {Array.from({ length: lines }).map((_, index) => (
          <div
            key={index}
            className={cn(
              'h-4',
              index === lines - 1 ? 'w-3/4' : 'w-full',
              getVariantClasses(),
              getAnimationClass()
            )}
          />
        ))}
      </div>
    );
  }

  return (
    <div
      className={cn(
        'h-4 w-full',
        getVariantClasses(),
        getAnimationClass(),
        className
      )}
    />
  );
}

/**
 * 内容加载状态组件
 */
interface ContentLoadingProps {
  isLoading: boolean;
  children: React.ReactNode;
  skeleton?: React.ReactNode;
  className?: string;
  variant?: 'fade' | 'blur';
}

export function ContentLoading({
  isLoading,
  children,
  skeleton,
  className,
  variant = 'fade',
}: ContentLoadingProps) {
  const getTransitionClasses = () => {
    switch (variant) {
      case 'blur':
        return cn(
          'transition-all duration-300',
          isLoading ? 'blur-sm opacity-50' : 'blur-0 opacity-100'
        );
      default:
        return cn(
          'transition-opacity duration-300',
          isLoading ? 'opacity-50' : 'opacity-100'
        );
    }
  };

  return (
    <div className={cn('relative', className)}>
      {isLoading && skeleton && (
        <div className="absolute inset-0 z-10">{skeleton}</div>
      )}
      <div className={getTransitionClasses()}>{children}</div>
    </div>
  );
}

/**
 * 进度条组件
 */
interface ProgressBarProps {
  progress: number;
  className?: string;
  variant?: 'default' | 'gradient' | 'striped';
  size?: 'sm' | 'md' | 'lg';
  showLabel?: boolean;
  animated?: boolean;
}

export function ProgressBar({
  progress,
  className,
  variant = 'default',
  size = 'md',
  showLabel = false,
  animated = false,
}: ProgressBarProps) {
  const getSizeClasses = () => {
    switch (size) {
      case 'sm':
        return 'h-1';
      case 'lg':
        return 'h-4';
      default:
        return 'h-2';
    }
  };

  const getVariantClasses = () => {
    switch (variant) {
      case 'gradient':
        return 'bg-gradient-to-r from-blue-500 to-purple-600';
      case 'striped':
        return 'bg-blue-600 bg-[length:1rem_1rem] bg-[linear-gradient(45deg,rgba(255,255,255,.15)_25%,transparent_25%,transparent_50%,rgba(255,255,255,.15)_50%,rgba(255,255,255,.15)_75%,transparent_75%,transparent)]';
      default:
        return 'bg-blue-600';
    }
  };

  return (
    <div className={cn('w-full', className)}>
      {showLabel && (
        <div className="flex justify-between text-sm text-gray-600 dark:text-gray-400 mb-1">
          <span>进度</span>
          <span>{Math.round(progress)}%</span>
        </div>
      )}
      <div
        className={cn(
          'w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden',
          getSizeClasses()
        )}
      >
        <div
          className={cn(
            'h-full transition-all duration-300 ease-out rounded-full',
            getVariantClasses(),
            animated &&
              variant === 'striped' &&
              'animate-[progress-stripes_1s_linear_infinite]'
          )}
          style={{ width: `${Math.min(100, Math.max(0, progress))}%` }}
        />
      </div>
    </div>
  );
}

/**
 * 加载状态Hook
 */
export function useLoading(initialState = false) {
  const [isLoading, setIsLoading] = useState(initialState);
  const [progress, setProgress] = useState(0);
  const [message, setMessage] = useState('');

  const startLoading = useCallback((msg?: string) => {
    setIsLoading(true);
    setProgress(0);
    if (msg) setMessage(msg);
  }, []);

  const stopLoading = useCallback(() => {
    setIsLoading(false);
    setProgress(100);
  }, []);

  const updateProgress = useCallback((value: number, msg?: string) => {
    setProgress(value);
    if (msg) setMessage(msg);
  }, []);

  const updateMessage = useCallback((msg: string) => {
    setMessage(msg);
  }, []);

  return {
    isLoading,
    progress,
    message,
    startLoading,
    stopLoading,
    updateProgress,
    updateMessage,
  };
}
